﻿namespace Knownet.AST
{
  using System;
  using System.Collections.Generic;
  using System.Text;

  /// <summary>
  /// 语法节点。
  /// </summary>
  /// <remarks>
  /// 语法节点是最基本的结构。
  /// 一个语法节点由它的先前语法节点，
  /// 后继语法节点和蕴涵的语法节点构成。
  /// 语法节点的有效组合可以构成一个BNF，
  /// 或者实现BNF的语句结构，例如一段
  /// 实现指定BNF的程序代码或者自然语言
  /// 片断等。
  /// 语法节点可以构成BNF，这意味着语法
  /// 节点也可以构成任何有效的语法定义结构。
  /// 这包括从语义网络直接抽象的任何有效
  /// 定义。由语法节点的结构支持，我们可以
  /// 从代码或者自然语言的片断中直接抽象
  /// 语法定义。这就实现了语言系统的知识
  /// 积累。
  /// </remarks>
  public class SyntaxNode
  {
    #region Statics
    public static SyntaxNode CreateInstance()
    {
      return new SyntaxNode();
    }
    #endregion
    #region Fields
    /// <summary>
    /// 语法节点的签名。
    /// </summary>
    protected string signature = string.Empty;
    /// <summary>
    /// 语法节点的前驱节点。
    /// </summary>
    protected SyntaxNode precedingNode = null;
    /// <summary>
    /// 语法节点的后继节点。
    /// </summary>
    protected SyntaxNode followingNode = null;
    /// <summary>
    /// 语法节点的蕴涵节点（链表）。
    /// </summary>
    protected List<SyntaxNode> containingNodes = null;
    #endregion
    #region Properties
    /// <summary>
    /// 获取或者设置语法节点的签名。
    /// </summary>
    public virtual string Signature
    {
      get
      {
        return this.signature;
      }
      set
      {
        this.signature = value;
      }
    }
    /// <summary>
    /// 获取前驱节点。
    /// </summary>
    public virtual SyntaxNode PrecedingNode
    {
      get
      {
        return this.precedingNode;
      }
    }
    /// <summary>
    /// 获取后继节点。
    /// </summary>
    public virtual SyntaxNode FollowingNode
    {
      get
      {
        return this.followingNode;
      }
    }
    /// <summary>
    /// 判别当前节点是否具有前驱节点。
    /// </summary>
    public virtual bool HasPreceding
    {
      get
      {
        return this.precedingNode != null;
      }
    }
    /// <summary>
    /// 判别当前节点是否具有后继节点。
    /// </summary>
    public virtual bool HasFollowing
    {
      get
      {
        return this.followingNode != null;
      }
    }
    /// <summary>
    /// 判别当前节点是否含有内涵节点。
    /// </summary>
    public virtual bool HasContainingNodes
    {
      get
      {
        return this.containingNodes != null && this.containingNodes.Count > 0;
      }
    }
    /// <summary>
    /// 获取内涵节点列表。
    /// </summary>
    public virtual List<SyntaxNode> ContainingNodes
    {
      get
      {
        return this.containingNodes == null ?
          this.containingNodes = new List<SyntaxNode>(0):
          this.containingNodes;
      }
    }
    /// <summary>
    /// 判别当前节点是否是头节点。
    /// </summary>
    /// <remarks>
    /// 由于采用链式结构和内涵列表结构的组合，
    /// 我们完全可以判断一个节点是否是链上的
    /// 头节点。其条件为：如果节点没有前驱
    /// 节点，那么它是头节点；否则（即节点
    /// 具有前驱节点），如果前驱节点蕴涵
    /// 这个节点，那么它是头节点。
    /// </remarks>
    public virtual bool IsHead
    {
      get
      {
        return !this.HasPreceding ? true :
          this.precedingNode.ContainingNodes.Contains(this);
      }
    }
    /// <summary>
    /// 判别当前节点是否是尾节点。
    /// </summary>
    /// <remarks>
    /// 由于采用链式结构和内涵列表结构的组合，
    /// 我们完全可以判断一个节点是否是链上的
    /// 尾节点。其条件为：如果节点没有后继
    /// 节点，那么它是尾节点；否则（即节点
    /// 具有后继节点），如果后继节点蕴涵
    /// 这个节点，那么它是尾节点。
    /// </remarks>
    public virtual bool IsTail
    {
      get
      {
        return !this.HasFollowing ? true :
          this.followingNode.ContainingNodes.Contains(this);
      }
    }
    #endregion
    #region Constructors
    public SyntaxNode() : this(String.Empty) { }
    public SyntaxNode(string signature):this(signature,null,null)
    {
    }
    public SyntaxNode(string signature,SyntaxNode precedingNode,SyntaxNode followingNode,params SyntaxNode[] containingNodes)
    {
      this.signature = signature;
      this.precedingNode = precedingNode;
      this.followingNode = followingNode;
      this.AddContainingNodes(containingNodes);
    }
    #endregion
    #region Methods
    /// <summary>
    /// 判别当前语法节点是否为给定语法节点的别名。
    /// </summary>
    /// <param name="node">给定语法节点。</param>
    /// <returns>如果是别名，返回true；否则返回false。</returns>
    public virtual bool IsAliasOf(SyntaxNode node)
    {
      return node!=null? this.signature == node.signature :false;
    }
    /// <summary>
    /// 在当前节点之前添加。
    /// </summary>
    /// <param name="node">需添加的节点</param>
    /// <returns>需添加的节点</returns>
    public virtual SyntaxNode AddNodeBefore(SyntaxNode node)
    {
      if (node != null)
      {
        SyntaxNode hcontainer = this.IsHead ? this.PrecedingNode : null;

        node.precedingNode = this.precedingNode;
        node.followingNode = this;

        if (this.HasPreceding)
        {
          this.precedingNode.followingNode = node;
          this.precedingNode = node;
        }

        if (hcontainer != null)
        {
          hcontainer.ContainingNodes.Insert(hcontainer.ContainingNodes.IndexOf(this), node);
          hcontainer.ContainingNodes.Remove(this);
        }
      }
      return node;

    }
    /// <summary>
    /// 在当前节点之后添加。
    /// </summary>
    /// <param name="node">需添加的节点</param>
    /// <returns>需添加的节点</returns>
    public virtual SyntaxNode AddNodeAfter(SyntaxNode node)
    {
      if (node != null)
      {
        SyntaxNode tcontainer = this.IsTail ? this.FollowingNode : null;

        node.followingNode = this.followingNode;
        node.precedingNode = this;

        if (this.HasFollowing)
        {
          this.followingNode.precedingNode = node;
          this.followingNode = node;
        }
        if (tcontainer != null)
        {
          tcontainer.ContainingNodes.Insert(tcontainer.ContainingNodes.IndexOf(this), node);
          tcontainer.ContainingNodes.Remove(this);
        }
      }
      return node;
    }
    /// <summary>
    /// 从链表中移除当前节点。
    /// </summary>
    /// <returns>当前节点。</returns>
    public virtual SyntaxNode RemoveNode()
    {
      SyntaxNode hcontainer = this.IsHead ? this.PrecedingNode : null;
      SyntaxNode tcontainer = this.IsTail ? this.FollowingNode : null;

      if (this.HasPreceding)
      {
        this.precedingNode.followingNode = this.followingNode;
      }
      if (this.HasFollowing)
      {
        this.followingNode.precedingNode = this.precedingNode;
      }

      if (hcontainer != null)
      {
        hcontainer.ContainingNodes.Remove(this);
      }
      if (tcontainer != null)
      {
        tcontainer.ContainingNodes.Remove(this);
      }

      this.precedingNode = null;
      this.followingNode = null;
      
      return this;
    }
    /// <summary>
    /// 添加内涵节点。
    /// </summary>
    /// <param name="nodes">内涵节点。</param>
    /// <returns>当前节点。</returns>
    public virtual SyntaxNode AddContainingNodes(params SyntaxNode[] nodes)
    {
      if (nodes != null)
      {
        this.ContainingNodes.AddRange(nodes);
      }
      return this;
    }
    /// <summary>
    /// 移除内涵节点。
    /// </summary>
    /// <param name="nodes">内涵节点。</param>
    /// <returns>当前节点。</returns>
    public virtual SyntaxNode RemoveContainingNodes(params SyntaxNode[] nodes)
    {
      if (this.HasContainingNodes && nodes !=null)
      {
        foreach(SyntaxNode node in nodes)
        {
          this.ContainingNodes.Remove(node);
        }
      }
      return this;
    }
    #endregion
  }

  ///如何使用SyntaxNode描述已有的BNF：
  ///给定BNF：
  /// 
  /// A
  /// : X
  /// | B C D
  /// | E F
  /// ;
  /// 
  /// 其中A称为定义项，一个BNF定义结构只有一个定义项。
  /// B C D 称为子句项，一个BNF定义结构可以有多个子句项。
  /// X或者B或者E等称为基本项，一个BNF子句中含有一个或者一个以上的基本项。
  /// 
  /// 我们使用一个名称（签名）为A的语法节点。然后使它的蕴涵节点列表包含
  /// 一系列的用于表达BNF定义结构中子句的语法节点。
  /// 例如包含：
  ///  X     子句
  ///  B C D 子句
  ///  E F   子句
  /// 
  /// 其中任何一个子句，例如“B C D”，都对应于一个基本项的链表。就这个例子
  /// 而言，A的蕴涵节点中只记录B。B的后继节点记录C，C的后继节点记录D。而B的
  /// 先前节点，在这个前提下记录A，C的先前节点记录B，D的先前节点记录C；最后，
  /// D的后继节点仍然记录A。
  /// 
  /// 可以看出，定义A被关联在含有B，C，D的闭环上；此外，A还被关联在含有X，
  /// 以及E和F的闭环上。
  /// 
  /// 名称为A的BNF定义结构，在语法节点构成的网络中呈献多个环经过同一节点
  /// 的结构。
  /// 
  /// 从BNF转化为语义节点的对应结构，一定要注意可选和重复。
  /// 
  /// 
  /// 如何处理可选：
  /// 
  /// 如何处理重复：
  /// 
  /// 
}
